package h0809;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
import java.util.StringJoiner;

/**
  * @description 伐木工 主要看这个解法
  * @author 不知名帅哥
  * @date 2024/8/9 12:23
  * @version 1.0
*/
public class WoodLopper {
    static class Wood{
        int profit; //记录木材的最大收益
        ArrayList<Integer> slices=new ArrayList<>(); //记录木材最大收益时对应的切割状态
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int x = sc.nextInt();
        Wood[] dp=new Wood[x+1];

        for (int i = 0; i <=x ; i++) {
            //初始时将木材不收割的收益作为最大收益
            dp[i]=new Wood();
            dp[i].profit=i;
            //这里初始化表示的切割状态指的是整段木头。理解错了。还以为是分成i块
            dp[i].slices.add(i);
        }

        //从长度为2的木材开始尝试切割
        for (int i = 2; i <=x ; i++) {
            for (int j = 1; j < i; j++) {
                int profit=dp[j].profit*dp[i-j].profit;
                //如果dp[j]和dp[i-j]的收益之和大于当前dp[i]的收益，更新dp[i]
                //TODO 关键步骤 (dp[i].slices.size()>dp[j].slices.size()+dp[i-j].slices.size())如果有更优的切割方案，更新dp[i].slices
                if (profit>dp[i].profit||
                        profit==dp[i].profit&&(dp[i].slices.size()>dp[j].slices.size()+dp[i-j].slices.size())){
                    dp[i].profit=profit;
                    dp[i].slices.clear();
                    dp[i].slices.addAll(dp[j].slices);
                    dp[i].slices.addAll(dp[i-j].slices);
                }
            }
        }

        // dp[x].slices记录的是：长度x的木材对应的最大收益的切割方案
        // 按题目输出描述要求进行升序
        dp[x].slices.sort(Comparator.comparingInt(a -> a));
        ArrayList<Integer> res = dp[x].slices;
        StringJoiner joiner=new StringJoiner(" ");
        for (Integer i : res) {
            joiner.add(i+"");
        }
        System.out.println(joiner);
    }
}














